package com.wangsd.web.api;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.util.SignUtils;
import com.wangsd.common.basicbean.Result;
import com.wangsd.common.component.WeixinPayService;
import com.wangsd.common.utils.AliClientUtil;
import com.wangsd.common.utils.PayUtil;
import com.wangsd.web.MyController;
import com.wangsd.web.report.entity.BillRecord;
import com.wangsd.web.report.entity.Merchant;
import com.wangsd.web.report.entity.ServiceBusiness;
import com.wangsd.web.report.entity.TOrder;
import com.wangsd.web.report.service.BillRecordService;
import com.wangsd.web.report.service.MerchantService;
import com.wangsd.web.report.service.ServiceBusinessService;
import com.wangsd.web.report.service.TOrderService;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/api/report")
@Slf4j
public class ApiController extends MyController {

    @Value("${service.url}")
    private String notifyUrl;
    @Value("${wx.pay.mchKey}")
    private String mchKey;

    @Value("${ali.pay.appId}")
    private String AliAppId;
    @Value("${ali.pay.privateKey}")
    private String AliPrivateKey;
    @Value("${ali.pay.publicKey}")
    private String AliPublicKey;
    @Value("${ali.pay.alipayCertPublicKey}")
    private String alipayCertPublicKey;
    @Value("${ali.pay.appCertPublicKey}")
    private String appCertPublicKey;
    @Value("${ali.pay.alipayRootCert}")
    private String alipayRootCert;
    @Value("${ali.pay.token}")
    private String AliToken;


    @Autowired
    BillRecordService billRecordService;
    @Autowired
    MerchantService merchantService;
    @Autowired
    WeixinPayService weixinPayService;
    @Autowired
    TOrderService orderService;
    @Autowired
    ServiceBusinessService serviceBusinessService;

    /**
     * 验证商户号是否存在
     *
     * @return
     */
    @ApiOperation(value = "验证商户号是否存在", notes = "验证商户号是否存在", httpMethod = "GET")
    @RequestMapping(value = "/checkMchId", method = RequestMethod.GET)
    @ResponseBody
    public Object checkMchId(@ApiParam(value = "商户号", required = true) @RequestParam String mchId) {
        Merchant merchant = merchantService.selectBySubMchId(mchId);
        if (merchant == null) {
            return Result.fail("商户信息不存在");
        }
        return Result.success();
    }

    /**
     * 验证商户号是否存在
     *
     * @return
     */
    @ApiOperation(value = "获取需要上报的账单", notes = "获取需要上报的账单", httpMethod = "GET")
    @RequestMapping(value = "/getBillList", method = RequestMethod.GET)
    @ResponseBody
    public Object getBillList(@ApiParam(value = "商户号", required = true) @RequestParam String mchId) {
        try {
            List<BillRecord> list = billRecordService.selectBySubMckIdAndStaus(mchId, 0);
            return Result.success(list);
        } catch (Exception e) {
            return Result.fail(e.getMessage());
        }
    }


    /**
     * 服务商微信扫码支付
     *
     * @return
     */
    @ApiOperation(value = "服务商微信扫码支付", notes = "服务商微信扫码支付", httpMethod = "GET")
    @RequestMapping(value = "/wxScanPay", method = RequestMethod.GET)
    @ResponseBody
    public Result wxScanPay(@ApiParam(value = "支付金额", required = true) @RequestParam Long totalFee,
                            @ApiParam(value = "服务商ID", required = true) @RequestParam Long businessId) {
        try {
            String outTradeNo = "SERVICE_SCAN_WX_" + System.currentTimeMillis();
            WxPayUnifiedOrderResult result = doWxPayOrder(totalFee, businessId, outTradeNo);
            if (result.getReturnCode().equals("SUCCESS") &&
                    result.getReturnCode().equals("SUCCESS")) {

                //创建本地订单
                ServiceBusiness business = serviceBusinessService.getById(businessId);
                TOrder order = new TOrder();
                order.setBusinessServiceId(businessId);
                order.setCode(business.getCode());
                order.setOrderStatus(0);
                order.setOrderTotalFee(totalFee);
                order.setPayType(1);
                order.setOutTradeNo(outTradeNo);
                orderService.saveOrUpdate(order);


                return Result.success(result.getCodeURL());
            } else {
                return Result.fail(result.getErrCodeDes());
            }
        } catch (WxPayException e) {
            e.printStackTrace();
            return Result.fail("获取二维码失败");
        }
    }

    /**
     * 服务商支付宝扫码支付
     *
     * @return
     */
    @ApiOperation(value = "服务商支付宝扫码支付", notes = "服务商支付宝扫码支付", httpMethod = "GET")
    @RequestMapping(value = "/aliScanPay", method = RequestMethod.GET)
    @ResponseBody
    public Result aliScanPay(@ApiParam(value = "支付金额", required = true) @RequestParam Long totalFee,
                             @ApiParam(value = "服务商ID", required = true) @RequestParam Long businessId) {
        try {
            String outTradeNo = "SERVICE_SCAN_ALI_" + System.currentTimeMillis();
            AlipayTradePrecreateResponse result = doAliPayOrder(totalFee, businessId, outTradeNo);
            if (result.getCode().equals("10000")) {
                //创建本地订单
                ServiceBusiness business = serviceBusinessService.getById(businessId);
                TOrder order = new TOrder();
                order.setBusinessServiceId(businessId);
                order.setCode(business.getCode());
                order.setOrderStatus(0);
                order.setOrderTotalFee(totalFee);
                order.setPayType(2);
                order.setOutTradeNo(outTradeNo);
                orderService.saveOrUpdate(order);
                return Result.success(result.getQrCode());
            } else {
                return Result.fail(result.getSubMsg());
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return Result.fail("获取二维码失败");
        }
    }

    private AlipayTradePrecreateResponse doAliPayOrder(Long totalFee, Long businessId, String outTradeNo) throws AlipayApiException {
        CertAlipayRequest certAlipayRequest = AliClientUtil.initCertAlipayRequest(
                AliAppId, AliPrivateKey, appCertPublicKey, alipayCertPublicKey, alipayRootCert);
        AlipayClient alipayClient1 = new DefaultAlipayClient(certAlipayRequest);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();

        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setOutTradeNo(outTradeNo);
        model.setTotalAmount((totalFee * 0.01) + "");
        model.setSubject("服务费充值");
        //回调地址
        String notify = notifyUrl + "/api/report/aliScanNotify";
        request.setNotifyUrl(notify);
        request.setApiVersion("1.0");
        request.setBizModel(model);
        request.putOtherTextParam("app_auth_token", AliToken);
        AlipayTradePrecreateResponse response = alipayClient1.certificateExecute(request);
        return response;
    }

    private WxPayUnifiedOrderResult doWxPayOrder(Long totalFee, Long businessId, String outTradeNo) throws WxPayException {
        WxPayService wxPayService = weixinPayService.getService(true);
        //创建微信预支付订单
        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
        request.setBody("充值服务费");
        request.setOutTradeNo(outTradeNo);
        request.setProductId(businessId + "");
        request.setTotalFee(Integer.valueOf(totalFee + ""));
        request.setSpbillCreateIp("127.0.0.1");
        request.setNotifyUrl(notifyUrl + "/api/report/wxScanNotify");
        request.setTradeType("NATIVE");
        WxPayUnifiedOrderResult result = wxPayService.unifiedOrder(request);
        return result;
    }

    @ApiOperation(value = "支付宝支付回调", notes = "支付宝支付回调", httpMethod = "POST")
    @RequestMapping("/aliScanNotify")
    @ResponseBody
    public void aliScanNotify() {
        String str = "success";
        try {
            //获取支付宝POST过来反馈信息
            Map<String, String> maps = new HashMap<String, String>();
            Map requestParams = request.getParameterMap();
            for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                maps.put(name, valueStr);
            }
            //调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCertCheckV1(maps, alipayCertPublicKey, "UTF-8", "RSA2");
            if (signVerified) {
                String tradeStatus = maps.get("trade_status");
                String outTradeNo = maps.get("out_trade_no");
                String totalAmount = maps.get("total_amount");
                String tradeNo = maps.get("trade_no");
                if (tradeStatus.equals("TRADE_SUCCESS")) {//订单支付成功

                    TOrder order = orderService.selectByOutTradeNo(outTradeNo);

                    if (order != null && order.getOrderStatus() == 0) {//待支付状态
                        TOrder upOrder = new TOrder();
                        upOrder.setId(order.getId());
                        upOrder.setOrderStatus(1);
                        upOrder.setTransactionId(tradeNo);
                        upOrder.setOrderTotalFee((long)(Double.valueOf(totalAmount) * 100));
                        orderService.saveOrUpdate(upOrder);

                        ServiceBusiness business = serviceBusinessService.getById(order.getBusinessServiceId());
                        ServiceBusiness upBusiness = new ServiceBusiness();
                        upBusiness.setId(business.getId());
                        upBusiness.setTotalFee(business.getTotalFee() + Double.valueOf(totalAmount));
                        serviceBusinessService.saveOrUpdate(upBusiness);
                    }
                }
            } else {
                str = "failure";
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        } finally {
            try {
                response.getWriter().write(str);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @ApiOperation(value = "微信支付回调", notes = "微信支付回调", httpMethod = "GET")
    @RequestMapping("/wxScanNotify")
    @ResponseBody
    public void wxScanNotify(@RequestBody(required = false) String requestBody) {
        String returnXml = "<xml>"
                + "<return_code><![CDATA[SUCCESS]]></return_code>"
                + "<return_msg><![CDATA[OK]]></return_msg>"
                + "</xml> ";
        try {
            log.info("接收到的报文：" + requestBody);
            Map map = PayUtil.doXMLParse(requestBody);
            String returnCode = map.get("return_code").toString();
            String resultCode = map.get("result_code").toString();
            //商户订单号
            String outTradeNo = map.get("out_trade_no").toString();
            String wxSign = map.get("sign").toString();
            String transactionId = map.get("transaction_id").toString();
            Long cashFee = Long.valueOf(map.get("cash_fee").toString());
            Long totalFee = Long.valueOf(map.get("total_fee").toString());

            //检查执行结果
            if (WxPayConstants.ResultCode.SUCCESS.equals(returnCode)//执行结果成功
                    && WxPayConstants.ResultCode.SUCCESS.equals(resultCode)) {//业务结果成功

                TOrder order = orderService.selectByOutTradeNo(outTradeNo);
                //支付中的订单，防止重复处理
                if (order != null && order.getOrderStatus() == 0) {//待支付状态
                    String mySign = SignUtils.createSign(map, "MD5", mchKey, new String[0]);
                    if (wxSign.equals(mySign)) {//签名验证成功
                        TOrder upOrder = new TOrder();
                        upOrder.setId(order.getId());
                        upOrder.setOrderStatus(1);
                        upOrder.setTransactionId(transactionId);
                        upOrder.setRealPayFee(cashFee);
                        upOrder.setOrderTotalFee(totalFee);
                        orderService.saveOrUpdate(upOrder);

                        ServiceBusiness business = serviceBusinessService.getById(order.getBusinessServiceId());
                        ServiceBusiness upBusiness = new ServiceBusiness();
                        upBusiness.setId(business.getId());
                        upBusiness.setTotalFee(business.getTotalFee() + (totalFee * 0.01));
                        serviceBusinessService.saveOrUpdate(upBusiness);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.getWriter().write(returnXml);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
